#ifndef __ENP_CTRL_H__
#define __ENP_CTRL_H__

#include "base/CTStringUtils.h"

#include "enpdef.h"
#include "enpconfig.h"
#include "enplisten.h"
#include "enpclientfactory.h"
#include "enpclient.h"
#include "flowctrl.h"

using namespace CTLib;

//===============================================

#define CEnpEpollObject CTEpollObject<CEnpCtrl>

#define FLASH_POLICY_STRING "<policy-file-request/>"
#define FLASH_POLICY_STRING_LEN 23

// enp主控对象
class CEnpCtrl
{
    enum
    {
        BUFF_INDEX = 0,
        FREE_LIST = 0,
        USED_LIST = 1,
    };

public:
    friend class CEnpClient;
    friend class CEnpListen;

	CEnpCtrl();

	// 初始化
	int Init();

	// 主循环
	int Run();

    int Exit();

    void OnShmQueueEvent(CEnpEpollObject* pstObject, SOCKET iSocket, int iEvent);
    void OnListenEvent(CEnpEpollObject* pstObject, SOCKET iSocket, int iEvent);
    void OnClientEvent(CEnpEpollObject* pstObject, SOCKET iSocket, int iEvent);

protected:
    void HandleShmQueueMsg(int iShmQueueIndex);

    int AllocRecvBuffer(CEnpClient* pstClient);
    int AllocSendBuffer(CEnpClient* pstClient);
    int FreeRecvBuffer(CEnpClient* pstClient);
    int FreeSendBuffer(CEnpClient* pstClient);

	// 发呆检测
	int CheckIdle();

    // 发送残留数据
    int CheckRemain();

	// 把RecvBuf中的消息放入接收队列
    int PutOneMessage(CEnpClient* pstClient, int iLen, const char* szMsgBuf, int iMsgLen);

	// 向上层发送Notify
	int PutOneNotify(CEnpClient* pstClient, unsigned short unLiveFlag);
    int PutOneNotify(CEnpNetHead& stNetHead, unsigned short unLiveFlag, int iShmQueueIndex);

	void DumpNetHead(CEnpNetHead& stHead);
	void DumpHandleInfo(CEnpClient* pstClient);
	void DumpStatInfo();

	/**
	* 判断RecvBuf中是否有完整的消息.
    * @param[out] iLen 是整个消息的长度
    * @param[out] pszMsgLen 是消息中有效数据的起始位置
    * @param[out] iMsgLen 是消息中有效数据的长度
	*/
	int BufferHasMessage(CEnpClient* pstClient, int& iLen, char*& pszMsgBuf, int& iMsgLen);

    bool FromAdmin(const CEnpNetHead& stHead);

	int RecvSocket(CEnpClient* pstClient);
	int SendSocket(CEnpClient* pstClient);
	int CloseSocket(CEnpClient* pstClient, unsigned short unLiveFlag);

    int AfterRecvSocket(CEnpClient* pstClient);
    int AfterSendSocket(CEnpClient* pstClient);

    bool IsPolicyString(CEnpClient* pstClient);
    int CheckPolicyString(CEnpClient* pstClient);

    static void sigusr1_handle(int iSigVal);
    static void sigusr2_handle(int iSigVal);

private:
	CTBuffer			    m_stTempBuf;		// 临时缓冲区

	CTEpoll				    m_stEpoll;

    CTShm				    m_stHandleMgrShm;
    CEnpClientFactory       m_stClientFactory;
    CTObjectMgr<char*>      m_stRecvBufMgr;
    CTObjectMgr<char*>      m_stSendBufMgr;

    // 监听端口
    CTArray<CEnpListen, ENP_MAX_LISTEN>              m_astListen;

    CTArray<CTShmQueue<CEnpCtrl>, ENP_MAX_SHM_QUEUE> m_astShmQueue;

	CTStat				m_stat;

    static bool         s_bReloadConfig;
    static bool         s_bExit;

	unsigned int		m_uiNow;

    CFlowCtrl           m_stFlowCtrl;           // 用于流量控制
};

#endif //__ENP_CTRL_H__
